package com.jerkin.easyexcl;

import com.alibaba.excel.EasyExcel;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import com.google.common.collect.Lists;
import com.jerkin.easyexcl.model.InvoiceDetail;
import com.jerkin.easyexcl.model.InvoiceInfo;
import org.apache.commons.collections4.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @version V1.0
 * @ClassName: ExclRead
 * @Description:
 * @author: huhongzhi
 * @date: 2019/12/16 19:12
 */
public class ExclRead {
    private static final String path = "C:\\Users\\huain\\Desktop\\1.xlsx";
    private static final String newPath = "D:\\carzone\\workspace\\非油品.xlsx";

    private static final String oilnewPath = "D:\\carzone\\workspace\\油品.xlsx";

    public static void main(String[] args) {
        EasyExcel.read(path, InvoiceDetail.class, new ReadListener()).sheet("销售单").doRead();
        EasyExcel.read(path, InvoiceDetail.class, new ReadListener()).sheet("售后单").doRead();
        List<InvoiceDetail> sales = ReadListener.getSales();
        List<InvoiceDetail> returns = ReadListener.getReturns();
        BigDecimal saleTotalPrice = sales.stream().map(InvoiceDetail::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal returnTotalPrice = returns.stream().map(InvoiceDetail::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        System.out.println("销售金额" + saleTotalPrice + "==退货金额" + returnTotalPrice + "==第一次合并总金额是:" + saleTotalPrice.subtract(returnTotalPrice));

        //先获取所有的销售
        Map<String, List<InvoiceDetail>> saleMap = sales.stream().collect(Collectors.groupingBy(InvoiceDetail::getBizNo));
        //获取所有的退货
        Map<String, List<InvoiceDetail>> retutrnMap = returns.stream().collect(Collectors.groupingBy(InvoiceDetail::getSaleOrderId));
        //先将当期冲减的去掉
        List<String> values = new ArrayList<>();
        List<String> saleValue = new ArrayList<>();
        List<BigDecimal> reduncePrice = new ArrayList<>();
        retutrnMap.forEach((k, v) -> {
            List<InvoiceDetail> invoiceDetails = saleMap.get(k);
            if (CollectionUtils.isEmpty(invoiceDetails)) {
                return;
            }
            //记录需要当期冲减的
            values.add(k);
            Map<String, InvoiceDetail> invoiceDetailMap =
                    invoiceDetails.stream().collect(Collectors.toMap(InvoiceDetail::getKzSkuCode, x -> x));
            List<InvoiceDetail> tempInvoiceDetail = new ArrayList<>();
            v.forEach(e -> {
                InvoiceDetail invoiceDetail = invoiceDetailMap.get(e.getKzSkuCode());
                invoiceDetail.setSaleNum(invoiceDetail.getSaleNum() - e.getSaleNum());
                if(invoiceDetail.getSaleNum()<0){
                    System.out.println("原数据"+JSONUtil.toJsonStr(invoiceDetail));
                    System.out.println("扣减数据"+JSONUtil.toJsonStr(invoiceDetail));
                }
                invoiceDetail.setTotalPrice(invoiceDetail.getTotalPrice().subtract(e.getTotalPrice()));

                if (invoiceDetail.getSaleNum() >= 0) {
//                    invoiceDetail.setPrice(invoiceDetail.getPrice().divide(BigDecimal.valueOf(100,2)));
                    /*invoiceDetail.setTotalPrice(invoiceDetail.getPrice().multiply(
                            BigDecimal.valueOf(invoiceDetail.getSaleNum())));*/
                    tempInvoiceDetail.add(invoiceDetail);
                }
//                if(invoiceDetail.getSaleNum() ==0){
//                    reduncePrice.add(e.getTotalPrice());
//                }
            });
            saleMap.put(k, Lists.newArrayList(invoiceDetailMap.values()));
//            if (CollectionUtils.isNotEmpty(tempInvoiceDetail)) {
//                saleMap.put(k, tempInvoiceDetail);
//            }
        });
//        BigDecimal returnPrice = BigDecimal.ZERO;
        List<BigDecimal> returnPrice = new ArrayList<>();
        values.forEach(e -> {
            returnPrice.add(retutrnMap.get(e).stream().map(InvoiceDetail::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add));
        });
        System.out.println("当期金额" + returnPrice.stream().reduce(BigDecimal.ZERO, BigDecimal::add));
        System.out.println("扣减金额" + reduncePrice.stream().reduce(BigDecimal.ZERO, BigDecimal::add));
        values.forEach(e -> {
            retutrnMap.remove(e);
        });
        saleValue.forEach(e -> {
            saleMap.remove(e);
        });


        //进行跨期冲减
        List<InvoiceDetail> saleInvoice = new ArrayList<>();
        saleMap.values().forEach(saleInvoice::addAll);

        List<InvoiceDetail> returnInvoice = new ArrayList<>();
        retutrnMap.values().forEach(returnInvoice::addAll);

        Map<String, List<InvoiceDetail>> saleInvoiceMap = saleInvoice.stream()
                .collect(Collectors.groupingBy(InvoiceDetail::getFlag));
        Map<String, List<InvoiceDetail>> returnInvoiceMap = returnInvoice.stream()
                .collect(Collectors.groupingBy(InvoiceDetail::getFlag));
        BigDecimal oilSaleTotalPrice = saleInvoiceMap.get("是").stream().map(InvoiceDetail::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal oilReturnTotalPrice1 = returnInvoiceMap.get("是").stream().map(InvoiceDetail::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        System.out.println("油品差异" + oilSaleTotalPrice.subtract(oilReturnTotalPrice1));
        BigDecimal noOilSaleTotalPrice = saleInvoiceMap.get("否").stream().map(InvoiceDetail::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal noOilReturnTotalPrice = returnInvoiceMap.get("否").stream().map(InvoiceDetail::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        System.out.println("非油品差异" + noOilSaleTotalPrice.subtract(noOilReturnTotalPrice));
        System.out.println("非油品退货" + noOilReturnTotalPrice);

//        saleInvoiceMap.forEach((k,v)->{
//            BigDecimal totalPrice = returnInvoiceMap.get(k)
//                    .stream().map(InvoiceDetail::getTotalPrice)
//                    .reduce(BigDecimal.ZERO,BigDecimal::add);
//            v.stream().sorted(Comparator.comparing(InvoiceDetail::getTotalPrice));
//            v.forEach(e->{
//                if(totalPrice.compareTo(BigDecimal.ZERO)>0){
//                    if(e.getSaleNum()>1){
//                        int num = e.getSaleNum()-1;
//                        BigDecimal price = e.getPrice().multiply(BigDecimal.valueOf(num));
//                        totalPrice = totalPrice.subtract(price);
//                    }
//                }
//            });
//        });
        List<BigDecimal> kou = new ArrayList<>();
        for (Map.Entry<String, List<InvoiceDetail>> entry : saleInvoiceMap.entrySet()) {
            BigDecimal totalPrice = returnInvoiceMap.get(entry.getKey())
                    .stream().map(InvoiceDetail::getTotalPrice)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            System.out.println(entry.getKey() + "退货金额-->" + totalPrice);

            for (InvoiceDetail invoiceDetail : entry.getValue()) {
                if (totalPrice.compareTo(BigDecimal.ZERO) > 0) {
                    if (invoiceDetail.getSaleNum() > 1) {
                        int num = invoiceDetail.getSaleNum() - 1;
                        BigDecimal price = invoiceDetail.getTotalPrice().subtract(invoiceDetail.getPrice());
                        if (totalPrice.compareTo(price) > 0) {
                            totalPrice = totalPrice.subtract(price);
                            kou.add(price);
                            invoiceDetail.setSaleNum(1);
                            invoiceDetail.setTotalPrice(invoiceDetail.getPrice());
                        } else {
                            int x = totalPrice.divide(invoiceDetail.getPrice(), 1, BigDecimal.ROUND_DOWN).intValue();
                            //如果不够一个单价，则是冲减价格
                            if (x > 0 && invoiceDetail.getSaleNum() > x) {
                                invoiceDetail.setSaleNum(invoiceDetail.getSaleNum() - x);
//                                invoiceDetail.setTotalPrice(invoiceDetail.getPrice().multiply(BigDecimal.valueOf(x)));
                                BigDecimal total = invoiceDetail.getPrice().multiply(BigDecimal.valueOf(x));
                                invoiceDetail.setTotalPrice(invoiceDetail.getTotalPrice().subtract(total));
                                totalPrice = totalPrice.subtract(total);
                            } else {
                                BigDecimal y = invoiceDetail.getPrice().divide(totalPrice.divide(BigDecimal.valueOf(invoiceDetail.getSaleNum()), 8, BigDecimal.ROUND_DOWN), 8, BigDecimal.ROUND_DOWN);
                                if (y.compareTo(BigDecimal.valueOf(2)) > 0) {
                                    invoiceDetail.setTotalPrice(invoiceDetail.getTotalPrice().subtract(totalPrice));
                                    totalPrice = BigDecimal.ZERO;
                                    invoiceDetail.setPrice(invoiceDetail.getTotalPrice().divide(BigDecimal.valueOf(invoiceDetail.getSaleNum()), 8, BigDecimal.ROUND_HALF_EVEN));
                                }
                            }

                        }

                    }
                }
            }

            BigDecimal noOilSaleTotalPrice1 = entry.getValue().stream().map(InvoiceDetail::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            System.out.println(entry.getKey() + "--->" + noOilSaleTotalPrice1.subtract(totalPrice));

            if (totalPrice.compareTo(BigDecimal.ZERO) > 0) {
                System.out.println("未扣减完");
            } else {
                Map<String, InvoiceInfo> map = new HashMap<>();
                Map<String, List<InvoiceDetail>> invoiceDetailMap = entry.getValue().stream().collect(Collectors.groupingBy(e -> {
                    return e.getKzSkuCode() + "-" + e.getPrice();
                }));

                invoiceDetailMap.forEach((k, v) -> {
                    v.forEach(e -> {
                        if (e.getSaleNum() <= 0) {
                            if (e.getSaleNum() < 0) {
                                System.out.println("数量小于的数据:" + JSONUtil.toJsonStr(e));
                            }
                            return;
                        }
                        if (e.getTotalPrice().compareTo(BigDecimal.ZERO) < 0) {
                            System.out.println(JSONUtil.toJsonStr(e));
                        }
                        InvoiceInfo invoice = map.get(k);
                        if (Objects.isNull(invoice)) {
                            invoice = new InvoiceInfo();
                            invoice.setKzSkuCode(e.getKzSkuCode());
                            invoice.setFlag(e.getFlag());
                            invoice.setPrice(e.getPrice());
                            invoice.setTotalPrice(e.getTotalPrice());
                            invoice.setRate("0.13");
                            invoice.setSupplierCode(e.getSupplierCode());
                            invoice.setName(e.getTypeName());
                            if (Objects.equals("否", invoice.getFlag())) {
                                invoice.setUnit(e.getUnit());
                                invoice.setSaleNum(BigDecimal.valueOf(e.getSaleNum()));
                            } else {
                                invoice.setUnit(e.getOilUnit());
                                invoice.setSaleNum(BigDecimal.valueOf(e.getSaleNum())
                                        .multiply(BigDecimal.valueOf(Double.valueOf(e.getAmount()))));
                                if (Objects.equals(e.getOilUnit(), "KG")) {
                                    invoice.setUnit("吨");
                                    invoice.setSaleNum(invoice.getSaleNum().divide(BigDecimal.valueOf(1000)));
                                }
                                invoice.setPrice(invoice.getTotalPrice().divide(invoice.getSaleNum(), 8, BigDecimal.ROUND_HALF_EVEN));
                            }
                        } else {
                            BigDecimal saleNum = BigDecimal.valueOf(e.getSaleNum());
                            if (Objects.equals(e.getFlag(), "是")) {
                                saleNum = BigDecimal.valueOf(e.getSaleNum()).multiply(BigDecimal.valueOf(Double.valueOf(e.getAmount())));
                                if (Objects.equals(e.getOilUnit(), "KG")) {
                                    saleNum = saleNum.divide(BigDecimal.valueOf(1000));
                                }
                            }
                            invoice.setSaleNum(invoice.getSaleNum().add(saleNum));
                            invoice.setTotalPrice(invoice.getTotalPrice().add(e.getTotalPrice()));
                        }
                        map.put(k, invoice);
                    });
                });
                BigDecimal price = map.values().stream().map(InvoiceInfo::getTotalPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
                System.out.println("处理完的总金额:" + price);
                if (Objects.equals("是", entry.getKey())) {
                    EasyExcel.write(oilnewPath, InvoiceInfo.class).sheet("模板").doWrite(Lists.newArrayList(map.values()));
                } else {
                    EasyExcel.write(newPath, InvoiceInfo.class).sheet("模板").doWrite(Lists.newArrayList(map.values()));
                }
            }

        }


    }
}
